package cn.hzc.fortess.system.controller;

import cn.hzc.fortess.system.common.EnableStatus;
import cn.hzc.fortess.core.common.ResponseData;
import cn.hzc.fortess.core.common.annotion.RequestPermission;
import cn.hzc.fortess.core.common.constant.Const;
import cn.hzc.fortess.core.common.BizErrorEnum;
import cn.hzc.fortess.core.common.exception.ServiceException;
import cn.hzc.fortess.core.shiro.ShiroKit;

import cn.hzc.fortess.system.entity.Dept;
import cn.hzc.fortess.system.entity.User;
import cn.hzc.fortess.system.eventbus.EventExecute;
import cn.hzc.fortess.system.eventbus.UserPwdChangeEvent;
import cn.hzc.fortess.system.search.UserSearch;
import cn.hzc.fortess.system.service.DeptService;
import cn.hzc.fortess.system.service.SettingService;
import cn.hzc.fortess.system.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Objects;

@Api(tags = {"用户管理"})
@Controller
@RequestMapping("/sam/user")
public class UserController extends BaseController {


    @Autowired
    private UserService userService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private SettingService settingService;

    @ApiIgnore
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String index() {
        return buildToView("index.html");
    }

    @ApiIgnore
    @RequestMapping("/add")
    public String addView(@RequestParam(required = false) Integer deptId) {
        User user = new User();
        user.setDeptId(deptId);
        user.setSex("M");
        user.setStatus(EnableStatus.ENABLE.getStatus());

        if (deptId != null) {
            Dept dept = deptService.getById(deptId);
            user.setLesseeId(dept.getLesseeId());
            user.setDeptName(dept.getDeptName());
        }

        //随机生成8位初始化密码
        user.setPassword(ShiroKit.getRandomString(8));
        setAttr("user", user);

        return buildToView("form.html");
    }

    @ApiIgnore
    @RequestMapping("/edit/{id}")
    public String editView(@PathVariable(value = "id", required = true) Integer userId) {
        User user = this.userService.getById(userId);
        user.setDeptName(deptService.getById(user.getDeptId()).getDeptName());
        setAttr("user", user);
        return buildToView("form.html");
    }

    @ApiIgnore
    @RequestMapping("/chpwd")
    public String chPwd() {
        return buildToView("password.html");
    }


    @ApiOperation("修改登录密码")
    @RequestMapping(value = "/changePwd", method = RequestMethod.POST)
    @ResponseBody
    public Object changePwd(@RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword) {
        Integer userId = ShiroKit.getUserNotNull().getId();
        this.userService.changePwd(getSession(), userId, oldPassword, newPassword);
        return ResponseData.success();
    }

    @ApiOperation("获取分页列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @RequestPermission("sam:user:list")
    @ResponseBody
    public Object page(UserSearch search) {

        if (search.getDeptId() != null && search.getDeptId() > 0) {
            Dept dept = deptService.getById(search.getDeptId());
            if (dept != null) {
                search.setParentCode(dept.getParentIds() + "[" + dept.getId() + "],");
            }
        }

        if (!ShiroKit.isAdmin()) {
            //只能看自己租户下的数据
            search.setLesseeId(ShiroKit.getUser().getLesseeId());
        }
        return this.userService.getPage(search);
    }

    private void checkAccount(User entity) {
        if (Const.ADMIN_LOGIN_NAME.equalsIgnoreCase(entity.getAccount())
                || "root".equalsIgnoreCase(entity.getAccount())) {
            throw new ServiceException(BizErrorEnum.USER_ALREADY_REG);
        }
        if (userService.getByLoginName(entity.getAccount()) != null) {
            throw new ServiceException(BizErrorEnum.USER_ALREADY_REG);
        }
    }

    @ApiOperation("新增用户")
    @RequestMapping(value = "/add.json", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:add")
    public ResponseData create(User entity) {
        checkAccount(entity);
        if (entity.getDeptId() == null || entity.getDeptId() == 0) {
            throw new ServiceException(BizErrorEnum.REQUEST_DEPT_PARENTID_ERROR);
        }
        final String pwd0 = entity.getPassword();//明文密码
        entity.setLesseeId(deptService.getById(entity.getDeptId()).getLesseeId());

        this.userService.add(entity);

        return ResponseData.success("用户创建成功，初始密码：" + pwd0);
    }

    @ApiOperation("编辑用户")
    @RequestMapping(value = "/edit.json", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:edit")
    public ResponseData edit(User entity) {
        if (Objects.equals(Const.ADMIN_USER_ID, entity.getUserId())
                && Objects.equals(entity.getStatus(), EnableStatus.DISABLE.getStatus())) {
            throw new ServiceException(BizErrorEnum.CANT_FREEZE_ADMIN);
        }
        if (entity.getDeptId() == null || entity.getDeptId() == 0) {
            throw new ServiceException(BizErrorEnum.REQUEST_DEPT_PARENTID_ERROR);
        }
        entity.setLesseeId(deptService.getById(entity.getDeptId()).getLesseeId());
        this.userService.update(entity);
        return ResponseData.success("用户信息编辑成功。");
    }

    @ApiOperation("删除用户")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:delete")
    public ResponseData delete(@PathVariable("id") Integer userId) {
        if (Objects.equals(userId, Const.ADMIN_USER_ID)) {
            throw new ServiceException(BizErrorEnum.CANT_DELETE_ADMIN_USER);
        }
        this.userService.delete(userId);
        return ResponseData.success();
    }

    @ApiOperation("修改用户状态")
    @RequestMapping(value = "/status", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:edit")
    public ResponseData editUserStatus(@RequestParam("userId") Integer userId, @RequestParam("status") Integer status) {
        if (Objects.equals(userId, Const.ADMIN_USER_ID)) {
            throw new ServiceException(BizErrorEnum.CANT_DELETE_ADMIN_USER);
        }
        this.userService.updateUserStatus(userId, status);
        return ResponseData.success();
    }


    @ApiOperation("重置用户密码")
    @RequestMapping(value = "/reset", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:reset")
    public ResponseData resetUserPwd(@RequestParam("userId") Integer userId) {
        User user = this.userService.getById(userId);
        if (Const.ADMIN_LOGIN_NAME.equals(user.getAccount())) {
            throw new ServiceException(BizErrorEnum.CANT_RESET_ADMIN_PWD);
        }

        user.setSalt(ShiroKit.getRandomSalt());

        final String newPwd =
                StringUtils.isNotBlank(user.getEmail()) ? ShiroKit.getRandomString(16)
                        : settingService.getValByKey("RESET_PWD", "a123456");

        user.setPassword(ShiroKit.md5(newPwd, user.getSalt()));
        this.userService.updateUserPwd(super.getSession(), user);
        if (StringUtils.isNotBlank(user.getEmail()) && Objects.equals(1, user.getStatus())) {
            EventExecute.me().post(new UserPwdChangeEvent(user, newPwd));
            return ResponseData.success("新密码已发送至用户邮箱：" + user.getEmail());
        }

        return ResponseData.success("新的密码：" + newPwd);
    }


    @ApiIgnore
    @RequestMapping("/role_assign/{id}")
    public String roleAssign(@PathVariable(value = "id", required = true) Integer userId, Model model) {
        model.addAttribute("userId", userId);
        return buildToView("user_roleassign.html");
    }

    @ApiOperation("分配用户角色")
    @RequestMapping(value = "/setRole", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:user:setRole")
    public ResponseData setRole(@RequestParam("userId") Integer userId, @RequestParam("roleIds") String roleIds) {
        if (userId == null || roleIds == null) {
            throw new ServiceException(BizErrorEnum.REQUEST_NULL);
        }

        if (userId.equals(Const.ADMIN_USER_ID)) {
            throw new ServiceException(BizErrorEnum.CANT_CHANGE_ADMIN);
        }
        this.userService.setRoles(userId, roleIds.split(","));
        return ResponseData.success();
    }


    @ApiIgnore
    @RequestMapping("/user_info")
    public String userInfo(Model model) {

        model.addAttribute("user", ShiroKit.getUserNotNull());
        return buildToView("user_info.html");
    }


    @Override
    protected String moduleName() {
        return "user";
    }
}
